const bcrypt = require('bcrypt');
const { Op } = require('sequelize');
const db = require('../models');
const Admin = db.Admin;
const Role = db.Role;

class AdminService {
    /**
     * 创建管理员账号
     * @param {Object} adminData - 管理员数据
     * @param {number} roleId - 角色ID
     * @returns {Promise<Admin>}
     */
    async createAdmin(adminData, roleId) {
        // 检查用户名是否已存在
        const existAdmin = await Admin.findOne({
            where: { username: adminData.username }
        });

        if (existAdmin) {
            throw new Error('用户名已存在');
        }

        // 密码加密
        const salt = await bcrypt.genSalt(10);
        adminData.password = await bcrypt.hash(adminData.password, salt);
        adminData.role_id = roleId;

        return await Admin.create(adminData);
    }

    /**
     * 根据ID获取管理员信息
     * @param {number} id - 管理员ID
     * @returns {Promise<Admin>}
     */
    async getAdminById(id) {
        return await Admin.findByPk(id, {
            include: [{ model: Role, as: 'role' }]
        });
    }

    /**
     * 更新管理员信息
     * @param {number} id - 管理员ID
     * @param {Object} updateData - 更新数据
     * @returns {Promise<Admin>}
     */
    async updateAdmin(id, updateData) {
        const admin = await Admin.findByPk(id);
        if (!admin) {
            throw new Error('管理员不存在');
        }

        // 如果更新密码，则加密
        if (updateData.password) {
            const salt = await bcrypt.genSalt(10);
            updateData.password = await bcrypt.hash(updateData.password, salt);
        }

        return await admin.update(updateData);
    }

    /**
     * 删除管理员(软删除)
     * @param {number} id - 管理员ID
     * @returns {Promise<boolean>}
     */
    async deleteAdmin(id) {
        const result = await Admin.destroy({
            where: { id }
        });
        return result > 0;
    }

    /**
     * 管理员登录验证
     * @param {string} username - 用户名
     * @param {string} password - 密码
     * @returns {Promise<Admin>}
     */
    async validateAdmin(username, password) {
        const admin = await Admin.findOne({
            where: { username }
        });

        if (!admin) {
            throw new Error('用户名或密码错误');
        }

        const isValid = await bcrypt.compare(password, admin.password);
        if (!isValid) {
            throw new Error('用户名或密码错误');
        }

        // 更新最后登录时间
        await admin.update({ last_login_time: new Date() });

        return admin;
    }

    /**
     * 检查管理员权限
     * @param {number} adminId - 管理员ID
     * @param {string} permission - 权限标识
     * @returns {Promise<boolean>}
     */
    async checkPermission(adminId, permission) {
        const admin = await Admin.findByPk(adminId, {
            include: [{ model: Role, as: 'role' }]
        });

        if (!admin || !admin.role) {
            return false;
        }

        // 检查权限字符串是否完全匹配
        if (admin.role.permissions.includes(permission)) {
            return true;
        }

        // 检查通配符权限 (如 "user.*" 匹配 "user.create", "user.delete" 或 "system:*" 匹配 "system:manage")
        const dotWildcard = permission.split('.').slice(0, -1).join('.') + '.*';
        const colonWildcard = permission.split(':').slice(0, -1).join(':') + ':*';
        if (admin.role.permissions.includes(dotWildcard) || admin.role.permissions.includes(colonWildcard)) {
            return true;
        }

        // 检查超级管理员权限
        if (admin.role.permissions.includes('*')) {
            return true;
        }

        return false;
    }

    /**
     * 获取管理员列表
     * @param {Object} query - 查询条件
     * @param {number} page - 页码
     * @param {number} pageSize - 每页数量
     * @returns {Promise<{rows: Admin[], count: number}>}
     */
    async getAdminList(query = {}, page = 1, pageSize = 10) {
        const where = {};

        if (query.username) {
            where.username = { [Op.like]: `%${query.username}%` };
        }

        if (query.status !== undefined) {
            where.status = query.status;
        }

        return await Admin.findAndCountAll({
            where,
            include: [{ model: Role, as: 'role' }],
            offset: (page - 1) * pageSize,
            limit: pageSize,
            order: [['createdAt', 'DESC']]
        });
    }
}

module.exports = new AdminService();